/**
 * 日历类
 */
package com.bit101.components {
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;

	[Event(name="select",type="flash.events.Event")]
	public class Calendar extends Panel {
		protected var _dateLabel:Label;
		protected var _day:int;
		protected var _dayButtons:Array = new Array();
		protected var _month:int;
		protected var _monthNames:Array = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		protected var _selection:Shape;
		protected var _year:int;

		/**
		 * Constructor
		 * @param parent 
		 * @param xpos The x 
		 * @param ypos The y 
		 */
		public function Calendar(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0){
			super(parent, xpos, ypos);
		}

		/**
		 * Initializes the component.
		 */
		protected override function init():void {
			super.init();
			setSize(140, 140);
			var today:Date = new Date();
			setDate(today);
		}

		/**
		 * 添加子项显示内容
		 */
		protected override function addChildren():void {
			super.addChildren();
			//添加每天的项6*7项
			for (var i:int = 0; i < 6; i++){  
				for (var j:int = 0; j < 7; j++){
					var btn:PushButton = new PushButton(this.content, j * 20, 21 + i * 20);
					btn.setSize(19, 19);
					btn.addEventListener(MouseEvent.CLICK, onDayClick);
					_dayButtons.push(btn);
				}
			}
			
			_dateLabel = new Label(this.content, 25, 0);
			_dateLabel.autoSize = true;
			
			var prevYearBtn:PushButton = new PushButton(this.content, 2, 2, "«", onPrevYear);
			prevYearBtn.setSize(14, 14);
			var prevMonthBtn:PushButton = new PushButton(this.content, 17, 2, "<", onPrevMonth);
			prevMonthBtn.setSize(14, 14);
			var nextMonthBtn:PushButton = new PushButton(this.content, 108, 2, ">", onNextMonth);
			nextMonthBtn.setSize(14, 14);
			var nextYearBtn:PushButton = new PushButton(this.content, 124, 2, "»", onNextYear);
			nextYearBtn.setSize(14, 14);
			
			_selection = new Shape();    //选择的背景
			_selection.graphics.beginFill(0xff0000, 0.15);
			_selection.graphics.drawRect(1, 1, 18, 18);
			this.content.addChild(_selection);
		}

		/**
		 * Gets the last day of the specfied month and year. Needed by layout.
		 * 返回每月的天数
		 * @param month 
		 * @param year 
		 * @return 
		 */
		protected function getEndDay(month:int, year:int):int {
			switch (month){
				case 0: // jan
				case 2: // mar
				case 4: // may
				case 6: // july
				case 7: // aug
				case 9: // oct
				case 11: // dec
					return 31;
					break;
				case 1: // feb 润年计算
					if ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0)))
						return 29;
					return 28;
					break;
				default:
					break;
			}
			// april, june, sept, nov.
			return 30;
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////
		/**
		 * 重新设置42项天的按钮label
		 * @param date The date to display.
		 */
		public function setDate(date:Date):void {
			_year = date.fullYear; //年
			_month = date.month;   //月
			_day = date.date;	   //日
			
			var startDay:int = new Date(_year, _month, 1).day; //星期值
			var endDay:int = getEndDay(_month, _year);
			for (var i:int = 0; i < 42; i++){
				_dayButtons[i].visible = false;
			}
			for (i = 0; i < endDay; i++){
				var btn:PushButton = _dayButtons[i + startDay];//起始星期
				btn.visible = true;
				btn.label = (i + 1).toString();
				btn.tag   = i + 1;
				if (i + 1 == _day){
					_selection.x = btn.x;
					_selection.y = btn.y;
				}
			}
			_dateLabel.text = _monthNames[_month] + "  " + _year;
			_dateLabel.draw();
			_dateLabel.x = (width - _dateLabel.width) / 2;
		}

		/**
		 * Displays specified date in calendar by drawing that month and year and highlighting the day.
		 * 设置日历的当前显示日期
		 * @param year
		 * @param month 
		 * @param day 
		 */
		public function setYearMonthDay(year:int, month:int, day:int):void {
			setDate(new Date(year, month, day));
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////
		/**
		 * 下一个月处理函数
		 */
		protected function onNextMonth(event:MouseEvent):void {
			_month++;
			if (_month > 11){
				_month = 0;
				_year++;
			}
			_day = Math.min(_day, getEndDay(_month, _year));
			setYearMonthDay(_year, _month, _day);
		}

		/**
		 * 上一个月处理函数
		 */
		protected function onPrevMonth(event:MouseEvent):void {
			_month--;
			if (_month < 0){
				_month = 11;
				_year--;
			}
			_day = Math.min(_day, getEndDay(_month, _year));
			setYearMonthDay(_year, _month, _day);
		}

		/**
		 * Advances the year forward by one.
		 */
		protected function onNextYear(event:MouseEvent):void {
			_year++;
			_day = Math.min(_day, getEndDay(_month, _year));
			setYearMonthDay(_year, _month, _day);
		}

		/**
		 * Moves the year back by one.
		 */
		protected function onPrevYear(event:MouseEvent):void {
			_year--;
			_day = Math.min(_day, getEndDay(_month, _year));
			setYearMonthDay(_year, _month, _day);
		}

		/**
		 * Called when a date button is clicked. Selects that date.
		 * 点击日期设置当前日期
		 * 派发出日期选择事件
		 */
		protected function onDayClick(event:MouseEvent):void {
			_day = event.target.tag;
			setYearMonthDay(_year, _month, _day);
			dispatchEvent(new Event(Event.SELECT));
		}

		///////////////////////////////////
		// getter/setters 返回选择的日期  年，月，日
		///////////////////////////////////
		/**
		 * Gets the currently selected Date.
		 * 返回选择的日期 
		 */
		public function get selectedDate():Date {
			var date:Date = new Date(_year, _month, _day)
			return date;
		}

		/**
		 * Gets the current month.
		 */
		public function get month():int {
			return _month;
		}

		/**
		 * Gets the current year.
		 */
		public function get year():int {
			return _year;
		}

		/**
		 * Gets the current day.
		 */
		public function get day():int {
			return _day;
		}
	}
}